#pragma once

#include <string>
#include <chrono>
#include <memory>
#include "MysqlResult.h"
#include "MysqlStatement.h"
#include "MysqlPreparedStatement.h"

namespace mysql {

    class MysqlConn {

    public:

        /**
          * @brief  初始化一个Mysql连接类
          */
        explicit MysqlConn();

        ~MysqlConn();

        /**
          * @brief  与指定数据库建立连接
          * @param  用户名，密码，数据库名，ip，端口
          * @retval 是否连接成功
          */
        void
        connect(const std::string &user, const std::string &password, const std::string &dbname, const std::string &ip,
                const unsigned short &port = 3306);

        /**
          * @brief  设置编码格式
          * @param  character_set 编码格式 默认为utf8
          */
        void setCharacterSet(const std::string &character_set = "utf8");

        /**
          * @brief  获取预处理操作对象
          * @retval 预处理操作对象的智能指针
          */
        std::shared_ptr<MysqlStatement> statement();

        /**
          * @brief  获取带参数的预处理操作对象
          * @param  要预处理的sql语句
          * @retval 带参数的预处理操作对象的智能指针
          */
        std::shared_ptr<MysqlPreparedStatement> prepareStatement(const std::string &sql);

        /**
          * @brief  获取错误信息
          * @retval 错误信息
          */
        std::string getError() const { return mysql_error(conn_); }

        /**
          * @brief  设置mysql事务提交模式
          * @param  true为1，false为0
          * @retval 是否设置成功
          */
        bool transaction(bool auto_mode) { return mysql_autocommit(conn_, auto_mode ? 1 : 0); }

        /**
          * @brief  提交事务
          * @retval 是否成功提交
          */
        bool commit() { return mysql_commit(conn_); }

        /**
          * @brief  回滚事务
          * @retval 是否成功回滚
          */
        bool rollBack() { return mysql_rollback(conn_); }

        /**
          * @brief 刷新起始的空闲时间点
          */
        void refreshAliveTime();

        /**
          * @brief  计算存活总时长
          * @retval 该连接已存活的毫秒
          */
        long long getAliveTime();

    private:

        // mysql连接上下文指针
        MYSQL *conn_ = nullptr;

        // 上一次刷新的时间点
        std::chrono::steady_clock::time_point alive_time_;

    };

}
